name: Publish and Sign Container Image
on:
  workflow_call:
    inputs:
      go-version:
        required: true
        type: string
      quay_image_name:
        required: false
        type: string
      ghcr_image_name:
        required: false
        type: string
      docker_image_name:
        required: false
        type: string
      platforms:
        required: true
        type: string
        default: linux/amd64
      push:
        required: true
        type: boolean
        default: false
      target:
        required: false
        type: string

    secrets:
      quay_username:
        required: false
      quay_password:
        required: false
      ghcr_username:
        required: false
      ghcr_password:
        required: false
      docker_username:
        required: false
      docker_password:
        required: false

    outputs:
      image-digest:
        description: "sha256 digest of container image"
        value: ${{ jobs.publish.outputs.image-digest }}

permissions: {}

jobs:
  publish:
    permissions:
      contents: read
      packages: write # Used to push images to `ghcr.io` if used.
      id-token: write # Needed to create an OIDC token for keyless signing
    runs-on: ubuntu-22.04
    outputs:
      image-digest: ${{ steps.image.outputs.digest }}
    steps:
      - name: Checkout code
        uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0
        with:
          fetch-depth: 0
          token: ${{ secrets.GITHUB_TOKEN }}
        if: ${{ github.ref_type == 'tag'}}

      - name: Checkout code
        uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0
        if: ${{ github.ref_type != 'tag'}}

      - name: Setup Golang
        uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
        with:
          go-version: ${{ inputs.go-version }}

      - name: Install cosign
        uses: sigstore/cosign-installer@1fc5bd396d372bee37d608f955b336615edf79c8 # v3.2.0
        with:
          cosign-release: 'v2.2.1'

      - uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v2.2.0
      - uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0

      - name: Setup tags for container image as a CSV type
        run: |
          IMAGE_TAGS=$(for str in \
            ${{ inputs.quay_image_name }} \
            ${{ inputs.ghcr_image_name }} \
            ${{ inputs.docker_image_name}}; do
            echo -n "${str}",;done | sed 's/,$//')

          echo $IMAGE_TAGS
          echo "TAGS=$IMAGE_TAGS" >> $GITHUB_ENV

      - name: Setup image namespace for signing, strip off the tag
        run: |
          TAGS=$(for tag in \
            ${{ inputs.quay_image_name }} \
            ${{ inputs.ghcr_image_name }} \
            ${{ inputs.docker_image_name}}; do
            echo -n "${tag}" | awk -F ":" '{print $1}' -;done)
          
            echo $TAGS
            echo 'SIGNING_TAGS<<EOF' >> $GITHUB_ENV
            echo $TAGS >> $GITHUB_ENV
            echo 'EOF' >> $GITHUB_ENV

      - name: Login to Quay.io
        uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.2.0
        with:
          registry: quay.io
          username: ${{ secrets.quay_username }}
          password: ${{ secrets.quay_password }}
        if: ${{ inputs.quay_image_name && inputs.push }}

      - name: Login to GitHub Container Registry
        uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.2.0
        with:
          registry: ghcr.io
          username: ${{ secrets.ghcr_username }}
          password: ${{ secrets.ghcr_password }}
        if: ${{ inputs.ghcr_image_name && inputs.push }}

      - name: Login to dockerhub Container Registry
        uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.2.0
        with:
          username: ${{ secrets.docker_username }}
          password: ${{ secrets.docker_password }}
        if: ${{ inputs.docker_image_name && inputs.push }}

      - name: Set up build args for container image
        run: |
            echo "GIT_TAG=$(if [ -z "`git status --porcelain`" ]; then git describe --exact-match --tags HEAD 2>/dev/null; fi)" >> $GITHUB_ENV
            echo "GIT_COMMIT=$(git rev-parse HEAD)" >> $GITHUB_ENV
            echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
            echo "GIT_TREE_STATE=$(if [ -z "`git status --porcelain`" ]; then echo "clean" ; else echo "dirty"; fi)" >> $GITHUB_ENV

      - name: Free Disk Space (Ubuntu)
        uses: jlumbroso/free-disk-space@4d9e71b726748f254fe64fa44d273194bd18ec91
        with:
          large-packages: false
          docker-images: false
          swap-storage: false
          tool-cache: false

      - name: Build and push container image
        id: image
        uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 #v5.1.0
        with:
          context: .
          platforms: ${{ inputs.platforms }}
          push: ${{ inputs.push }}
          tags: ${{ env.TAGS }}
          target: ${{ inputs.target }}
          provenance: false
          sbom: false
          build-args: |
            GIT_TAG=${{env.GIT_TAG}}
            GIT_COMMIT=${{env.GIT_COMMIT}}
            BUILD_DATE=${{env.BUILD_DATE}}
            GIT_TREE_STATE=${{env.GIT_TREE_STATE}}

      - name: Sign container images
        run: |
          for signing_tag in $SIGNING_TAGS; do
            cosign sign \
            -a "repo=${{ github.repository }}" \
            -a "workflow=${{ github.workflow }}" \
            -a "sha=${{ github.sha }}" \
            -y \
            "$signing_tag"@${{ steps.image.outputs.digest }}
          done
        if: ${{ inputs.push }}
